/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package bgu.sonar.util.ui.nodes;

import bgu.sonar.util.collections.obs.ObservableList;
import java.util.Collection;
import java.util.List;
import org.openide.nodes.ChildFactory;
import org.openide.nodes.Children;
import org.openide.nodes.Node;

/**
 *
 * @author bennyl
 */
public class ListNode<T> extends ExtendableNode {

    private ObservableList<T> list;
    private ValueNodeFactory<T> factory;

    public ListNode(ObservableList<T> list, ValueNodeFactory<T> factory) {
        this.list = list;
        this.factory = factory;

        setChildren(Children.create(new ListNodeChildren(list, factory), true));
    }

    public ObservableList<T> getList() {
        return list;
    }

    public static class ListNodeChildren<T> extends ChildFactory<T> implements ObservableList.ListListener<T> {

        private ObservableList<T> list;
        private ValueNodeFactory<T> factory;

        public ListNodeChildren(ObservableList<T> list, ValueNodeFactory<T> factory) {
            this.list = list;
            this.factory = factory;
            list.getListeners().add(this);
        }

        @Override
        protected boolean createKeys(List<T> toPopulate) {
            toPopulate.addAll(list);
            return true;
        }

        @Override
        protected Node createNodeForKey(T key) {
            return factory.createFor(key);
        }

        @Override
        public void onItemsAdded(ObservableList<T> list, Collection<T> items, int pos) {
            refresh(true);
        }

        @Override
        public void onItemsRemoved(ObservableList<T> list, Collection<T> items) {
            refresh(true);
        }

        @Override
        public void onListChanged(ObservableList<T> list) {
            refresh(true);
        }
    }

    public static interface ValueNodeFactory<V> {

        Node createFor(V value);
    }

    public static class DefaultValueNodeFactory implements ValueNodeFactory {

        @Override
        public Node createFor(Object value) {
            if (value instanceof Node) {
                return (Node) value;
            }
            return new ExtendableNode(value);
        }
    }
}
